﻿/* **************************************************************************
 *
 * Copyright 2007-2010 Jeff Hardy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * *************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Client.Win32;

namespace NWSGI.ManagementClient
{
    internal class WsgiEnvironPage : ModuleListPage, IModuleChildPage
    {
        public IModulePage ParentPage { get; set; }
        protected NwsgiModuleServiceProxy ServiceProxy { get; private set; }

        private WsgiEnvironItem SelectedItem
        {
            get { return ListView.SelectedItems.Count > 0 ? (WsgiEnvironItem)ListView.SelectedItems[0] : null; }
        }

        private PageTaskList taskList;
        protected override TaskListCollection Tasks
        {
            get
            {
                if(this.taskList == null)
                {
                    this.taskList = new PageTaskList(this);
                }

                TaskListCollection col = base.Tasks;
                col.Add(this.taskList);
                return col;
            }
        }

        protected override bool CanRefresh
        {
            get { return !base.InProgress; }
        }

        protected override void InitializeListPage()
        {
            string[] headers = new string[] { "Name", "Value" };

            foreach(string headerTitle in headers)
            {
                ColumnHeader header = new ColumnHeader();
                header.Text = headerTitle;
                header.Width = -2;
                ListView.Columns.Add(header);
            }

            ListView.LabelEdit = false;
            ListView.MultiSelect = false;

            ListView.ItemActivate += OnListViewItemActivate;
            ListView.SelectedIndexChanged += OnListViewSelectedIndexChanged;
            ListView.KeyUp += OnListViewKeyUp;
        }

        protected override void OnActivated(bool initialActivation)
        {
            base.OnActivated(initialActivation);
            if(initialActivation)
            {
                GetItemsAsync();
                ServiceProxy = (NwsgiModuleServiceProxy)CreateProxy(typeof(NwsgiModuleServiceProxy));
            }
        }

        protected override void Refresh()
        {
            if(CanRefresh)
                GetItemsAsync();
        }

        internal void GoBack()
        {
            base.Navigate(typeof(NwsgiPage));
        }

        private void GetItemsAsync()
        {
            Cursor.Current = Cursors.AppStarting;
            StartAsyncTask("Getting variables...", new DoWorkEventHandler(GetItems),
                                                   new RunWorkerCompletedEventHandler(GetItemsCompleted));
        }

        private void GetItems(object sender, DoWorkEventArgs e)
        {
            ArrayList variables = ServiceProxy.GetWsgiEnviron();
            List<WsgiEnvironInfo> items = new List<WsgiEnvironInfo>();

            foreach(string[] variable in variables)
            {
                items.Add(new WsgiEnvironInfo(variable));
            }

            e.Result = items;
        }

        private void GetItemsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ListView.BeginUpdate();
            ListView.Items.Clear();
            try
            {
                IEnumerable<WsgiEnvironInfo> variables = (IEnumerable<WsgiEnvironInfo>)e.Result;
                foreach(WsgiEnvironInfo value in variables)
                {
                    ListView.Items.Add(new WsgiEnvironItem(value));
                }
            }
            finally
            {
                base.Update();
                ListView.EndUpdate();
                Cursor.Current = Cursors.Default;
            }
        }

        private void OnListViewSelectedIndexChanged(object sender, EventArgs e)
        {
            base.Update();
        }

        private void OnListViewKeyUp(object sender, KeyEventArgs e)
        {
            if(this.SelectedItem != null && e.KeyData == Keys.Delete)
                this.DeleteItem();
        }

        private void OnListViewItemActivate(object sender, EventArgs e)
        {
            if(this.SelectedItem != null)
            {
                this.EditItem();
            }
        }

        private void AddItem(WsgiEnvironInfo entry, bool isSelected)
        {
            WsgiEnvironItem item = new WsgiEnvironItem(entry);
            base.ListView.Items.Add(item);

            if(isSelected)
            {
                item.Selected = true;
                item.Focused = true;
                base.ListView.EnsureVisible(item.Index);
            }
        }

        internal void AddScriptMapping()
        {
            using(WsgiEnvironEditor form = new WsgiEnvironEditor(base.Module, this.ServiceProxy))
            {
                if(base.ShowDialog(form) == DialogResult.OK)
                {
                    AddItem(form.Entry, true);
                }
            }
        }

        private void ReplaceItem(WsgiEnvironItem item, WsgiEnvironInfo entry)
        {
            base.ListView.Items.Remove(item);
            this.AddItem(entry, true);
        }

        internal void EditItem()
        {
            WsgiEnvironItem selectedItem = this.SelectedItem;
            if(selectedItem != null)
            {
                using(WsgiEnvironEditor form = new WsgiEnvironEditor(base.Module, this.ServiceProxy, selectedItem.Entry))
                {
                    if((base.ShowDialog(form) == DialogResult.OK) && form.HasChanges)
                    {
                        this.ReplaceItem(selectedItem, form.Entry);
                    }
                }
            }
        }

        internal void DeleteItem()
        {
            WsgiEnvironItem selectedItem = this.SelectedItem;
            if(selectedItem != null)
            {
                WsgiEnvironInfo entry = selectedItem.Entry;
                if(base.ShowMessage(string.Format("Are you sure you want to remove '{0}'? This cannot be undone.", new object[] { entry.Name }), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    try
                    {
                        Cursor.Current = Cursors.WaitCursor;
                        this.ServiceProxy.DeleteWsgiEnvironVariable(entry);
                        base.ListView.Items.Remove(selectedItem);
                    }
                    catch(Exception exception)
                    {
                        base.DisplayErrorMessage(exception, Resources.ResourceManager);
                    }
                    finally
                    {
                        Cursor.Current = Cursors.Default;
                    }
                }
            }
        }

        private sealed class PageTaskList : TaskList
        {
            private WsgiEnvironPage owner;

            public PageTaskList(WsgiEnvironPage owner)
            {
                this.owner = owner;
            }

            public override ICollection GetTaskItems()
            {
                ArrayList list = new ArrayList();

                list.Add(new MethodTaskItem("AddItem", "Add...", "Actions", "Add a new variable"));

                ListViewItem selected = this.owner.SelectedItem;
                if(selected != null)
                {
                    list.Add(new MethodTaskItem("EditItem", "Edit", "Actions", "Edit the currently selected variable"));
                    list.Add(new MethodTaskItem("DeleteItem", "Remove", "Actions", "Delete the currently selected variable"));
                }

                list.Add(new MethodTaskItem("GoBack", "Go Back", "Tasks", "Go back to the parent page"));

                return list;
            }

            public void AddItem()
            {
                this.owner.AddScriptMapping();
            }

            public void EditItem()
            {
                this.owner.EditItem();
            }

            public void DeleteItem()
            {
                this.owner.DeleteItem();
            }

            public void GoBack()
            {
                this.owner.GoBack();
            }
        }

        private sealed class WsgiEnvironItem : ListViewItem
        {
            public WsgiEnvironInfo Entry { get; private set; }

            public WsgiEnvironItem(WsgiEnvironInfo entry)
                : base(entry.ToArray())
            {
                Entry = entry;
            }
        }
    }

    internal class WsgiEnvironInfo
    {
        public string Name { get; set; }
        public string Value { get; set; }

        public WsgiEnvironInfo() { }

        public WsgiEnvironInfo(string[] values)
        {
            Name = values[0];
            Value = values[1];
        }

        public string[] ToArray()
        {
            return new string[] { Name, Value };
        }
    }
}
